﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;


namespace Marmat.Forms
{
    public class FileCollection : IList<FileItem>
    {
        private readonly FileManager FileManager;
        internal List<FileItem> list;

        internal FileCollection(FileManager FileManager)
        {
            this.list = new List<FileItem>();
            this.FileManager = FileManager;
        }

        /// <summary>
        /// 添加文件
        /// </summary>
        /// <param name="fileName">待上传的文件，含路径</param>
        /// <returns></returns>
        public FileItem Add(string fileName)
        {
            var info = new FileInfo(fileName);
            return this.Add(fileName, info.Name);
        }

        /// <summary>
        /// 添加文件
        /// </summary>
        /// <param name="fileName">待上传的文件，含路径</param>
        /// <param name="aliasName">文件的名称</param>
        /// <returns></returns>
        public FileItem Add(string fileName, string aliasName)
        {
            var info = new FileInfo(fileName);
            var item = new FileItem()
            {
                Id = this.FileManager.BuildFileID(fileName),
                Name = aliasName,
                Size = info.Length,
                LocalPath = fileName
            };
            this.Add(item);
            if (this.Contains(item))
            {
                return item;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 添加文件
        /// </summary>
        /// <param name="item"></param>
        public void Add(FileItem item)
        {
            var args = new FileItemCancelEventArgs(item);
            this.FileManager.OnBeforeAddFile(args);
            if (args.Cancel)
            {
                return;
            }

            if (this.Contains(item.Name))
            {
                throw new Exception("已经存在相同的文件。");
            }

            this.list.Add(item);
            this.AddCollection.Add(item);
            var args2 = new FileItemEventArgs(item);
            this.FileManager.OnAfterAddFile(args2);
            this.FileManager.SetValue();
            if (this.FileManager.BindingField.IsBinding)
            {
                this.FileManager.BindingField.WriteValue();
            }

            this.FileManager.Invalidate();
            if (this.FileManager.AutoSave)
            {
                this.FileManager.SaveChanges();
            }
        }

        public void Clear()
        {
            foreach (FileItem Item in this.list)
            {
                if (this.AddCollection.Contains(Item) == false)
                {
                    this.DelCollection.Add(Item);
                }
            }

            this.list.Clear();
            this.FileManager.SetValue();
            if (this.FileManager.BindingField.IsBinding)
            {
                this.FileManager.BindingField.WriteValue();
            }

            this.FileManager.Invalidate();
            if (this.FileManager.AutoSave)
            {
                this.FileManager.SaveChanges();
            }
        }

        /// <summary>
        /// 判断文件名是否存在文件管理器中。
        /// </summary>
        /// <param name="fileName">需要判断的文件名</param>
        /// <returns></returns>
        public bool Contains(string fileName)
        {
            return this.list.Exists(x => (x.Name ?? "") == (fileName ?? ""));
        }

        public bool Contains(FileItem item)
        {
            return this.list.Contains(item);
        }

        void ICollection<FileItem>.CopyTo(FileItem[] array, int arrayIndex)
        {
            this.list.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get
            {
                return this.list.Count;
            }
        }

        bool ICollection<FileItem>.IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public bool Remove(FileItem item)
        {
            bool result = false;
            var args = new FileItemCancelEventArgs(item);
            this.FileManager.RaiseBeforeRemoveFile(args);
            if (!args.Cancel)
            {
                if (this.DelCollection.Contains(item) == false)
                    this.DelCollection.Add(item);

                result = this.list.Remove(item);
                this.FileManager.SetValue();
                if (this.FileManager.BindingField.IsBinding)
                    this.FileManager.BindingField.WriteValue();

                this.FileManager.Invalidate();
                if (this.FileManager.AutoSave)
                {
                    this.FileManager.SaveChanges();
                }
            }

            return result;
        }

        public IEnumerator<FileItem> GetEnumerator()
        {
            return this.list.GetEnumerator();
        }

        public int IndexOf(FileItem item)
        {
            int result = this.list.IndexOf(item);
            this.FileManager.SetValue();
            return result;
        }

        public void Insert(int index, FileItem item)
        {
            this.list.Insert(index, item);
            this.FileManager.Invalidate();
            this.FileManager.SetValue();
            if (this.FileManager.BindingField.IsBinding)
            {
                this.FileManager.BindingField.WriteValue();
            }

            if (this.FileManager.AutoSave)
            {
                this.FileManager.SaveChanges();
            }
        }

        FileItem IList<FileItem>.this[int index]
        {
            get => this.list[index];
            set => this.list[index] = value;
        }

        /// <summary>
        /// 获取或设置指定索引处的元素。
        /// </summary>
        /// <param name="index">要获取或设置的元素的从零开始的索引。</param>
        /// <returns>指定索引处的元素。</returns>
        public FileItem this[int index]
        {
            get
            {
                return this.list[index];
            }
        }

        public void RemoveAt(int index)
        {
            this.list.RemoveAt(index);
            this.FileManager.SetValue();
            if (this.FileManager.BindingField.IsBinding)
            {
                this.FileManager.BindingField.WriteValue();
            }

            if (this.FileManager.AutoSave)
            {
                this.FileManager.SaveChanges();
            }

            this.FileManager.Invalidate();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.list.GetEnumerator();
        }

        internal List<FileItem> AddCollection
        {
            get
            {
                if (this._AddCollection is null)
                {
                    this._AddCollection = new List<FileItem>();
                }

                return this._AddCollection;
            }
        }

        private List<FileItem> _AddCollection;

        internal List<FileItem> DelCollection
        {
            get
            {
                if (this._DelCollection is null)
                {
                    this._DelCollection = new List<FileItem>();
                }

                return this._DelCollection;
            }
        }

        private List<FileItem> _DelCollection;
    }
}